#ifndef __NURBS_ATTRIBUTE__
#define __NURBS_ATTRIBUTE__

#include "defaults.h"

typedef boost::variant< std::vector<Vec2n>, std::vector<Vec3n>, std::vector<Vec4n>, std::vector<nfloat>, std::vector<bool>, std::vector<size_t>, std::vector<std::string> > Variant;

class Attribute {
public:
	void Add(const std::string& attribute, const Variant& v) {
		A.push_back(v);
		mapA[attribute] = A.size();
	}
	template<typename T>
	void Add(const std::string& attribute, const T& t) {
		Add(attribute, Variant(t));
	}
	
	size_t Handle(const std::string& attribute) const {return mapA[attribute] - 1;}
	size_t Size() const {return A.size();}
	bool Exist(const std::string& attribute) const {return mapA[attribute] == 0 ? false : true;}
	
	template<typename T>
	T& Get(size_t id, size_t attributeHandle) {
		std::vector<T>& x = boost::get< std::vector<T> >(A[attributeHandle]);
		return x[id];
	}
	
	template<typename T>
	const T& Get(size_t id, size_t attributeHandle) const {
		const std::vector<T>& x = boost::get< std::vector<T> >(A[attributeHandle]);
		return x[id];
	}
	
	template<typename T>
	T& Get(size_t id, const std::string& attribute) {
		size_t attributeHandle = Handle(attribute);
		return Get<T>(id, attributeHandle);
	}
	
	template<typename T>
	const T& Get(size_t id, const std::string& attribute) const {
		size_t attributeHandle = Handle(attribute);
		return Get<T>(id, attributeHandle);
	}
private:
	mutable std::map<std::string, size_t> mapA;
	std::vector<Variant> A;
};

#endif //__NURBS_ATTRIBUTE__


